package filechange;

import java.awt.Color;
import java.awt.Image;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.lang.reflect.Method;
import java.net.ConnectException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.AccessController;
import java.security.PrivilegedAction;

import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;

import org.apache.log4j.Logger;

import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageEncoder;
import com.sun.media.jai.codec.TIFFEncodeParam;
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;

public class FilesChanage {

	private static final Logger log = Logger.getLogger(FilesChanage.class);

	/**
	 * TXT文本内容转换成PDF文档 
	 * 
	 * @param filePath
	 *            文本文件地址
	 * @return String PDF文件地址
	 * @throws IOException
	 */
	public static String txtToPDF(String filePath) throws IOException {
		log.info("TXT文本内容转换成PDF文档");
		// 分析生成pdf文件路径
		String pdfFilePath = filePath.substring(0, filePath.lastIndexOf('.'))
				+ ".pdf";

		// 读取TXT文件内容
		FileReader file = null;
		String readLine = null;

		// 生成PDF文件
		File files = new File(pdfFilePath);
		// FileOutputStream out = null;
		Document document = null;

		PdfWriter writer = null;

		BufferedReader inputStream = null;

		try {
			// 创建文档,设置页面大小, 左、右、上和下页边距。
			document = new Document(PageSize.A4, 50, 50, 50, 50);
			// document是创建的文档,out是输出
			writer = PdfWriter.getInstance(document,
					new FileOutputStream(files));
			// 打开文档
			writer.setViewerPreferences(PdfWriter.PageModeUseOutlines);
			document.open();

			file = new FileReader(filePath);
			inputStream = new BufferedReader(file);
			BaseFont bfChinese = BaseFont.createFont(
					"c:\\WINDOWS\\Fonts\\simfang.ttf", BaseFont.IDENTITY_H,
					BaseFont.EMBEDDED);
			Font font = new Font(bfChinese, 15, Font.BOLD);
			while ((readLine = inputStream.readLine()) != null) {
				if (readLine.length() == 0) {
					readLine = " ";
				}
				// 写文本内容
				Paragraph text = new Paragraph(readLine, font);
				document.add(text);
			}
		} catch (DocumentException e) {
			log.debug("没有发现 c:\\WINDOWS\\Fonts\\simfang.ttf 字体");
			log.error(e.getMessage());
		} catch (FileNotFoundException e) {
			log.debug("没有发现需要转换的PDF文档");
			log.error(e.getMessage());
		} catch (IOException e) {
			log.debug("生成PDF文档错误");
			log.error(e.getMessage());
		} finally {
			if (document != null) {
				document.close();
			}
			if (inputStream != null) {
				inputStream.close();
			}
			if (file != null) {
				file.close();
			}
			if (writer != null) {
				writer.flush();
				writer.close();
			}
		}
		return pdfFilePath;
	}

	/**
	 * DOC转PDF文档
	 * 
	 * @param docFilePath
	 *            DOC文档地址
	 * @return int 转换成TIF文件的数量
	 */
	public static int docToPdf(String docFilePath) {
		log.info("DOC转PDF文档");
		File inputFile = new File(docFilePath);
		String newFilePath = docFilePath.substring(0, docFilePath.length() - 3)
				+ "pdf";
		File outputFile = new File(newFilePath);
		log.info("连接OpenOffice服务，实现PDF文档转换");
		OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
		try {
			connection.connect();
			DocumentConverter converter = new OpenOfficeDocumentConverter(
					connection);
			converter.convert(inputFile, outputFile);
			log.info("doc转换成PDF文档成功！");
		} catch (ConnectException cex) {
			log.error("连接OpenOffice错误");
		} finally {
			log.info("OpenOffice断开连接");
			if (connection != null) {
				connection.disconnect();
				connection = null;
			}
		}
		return pdfToJpg(newFilePath);
	}

	/**
	 * PDF转JPEG图片 <功能详细描述>
	 * 
	 * @param pdfFilePath
	 *            PDF文档路径
	 * @return int 转换成TIF文件的数量
	 */
	public static int pdfToJpg(String pdfFilePath) {
		log.info("PDF转JPEG图片");
		int pageAll = 0; // 总数量
		int pageAll_temp = 0;// 总数量
		File file = null;
		RandomAccessFile raf = null;
		FileChannel channel = null;
		FileOutputStream out = null;
		MappedByteBuffer buf = null;
		Image img = null;
		BufferedImage bufferImage = null;
		try {
			file = new File(pdfFilePath);
			raf = new RandomAccessFile(file, "r");
			channel = raf.getChannel();
			buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
			PDFFile pdffile = new PDFFile(buf);
			String filePath = pdfFilePath.substring(0, pdfFilePath.length()
					- file.getName().length());
			String filaName = file.getName().substring(0,
					file.getName().indexOf('.'));
			String newFileName = filePath + filaName;
			pageAll = pdffile.getNumPages();
			log.info("创建JPEG图片");
			for (int i = 1; i <= pageAll; i++) {
				PDFPage page = pdffile.getPage(i);
				Rectangle2D rect = new Rectangle2D.Double(0, 0, page.getBBox().getWidth(), page.getBBox().getHeight());
				img = page.getImage((int) rect.getWidth(),
						(int) rect.getHeight(), rect, null, true, true);
				bufferImage = new BufferedImage((int) rect.getWidth(),
						(int) rect.getHeight(), BufferedImage.TYPE_INT_RGB);
				bufferImage.getGraphics().drawImage(img, 0, 0, Color.WHITE,
						null);
				String newJPEGFileName = newFileName + i + ".jpg";
				String newTIFFileName = newFileName + i + ".tif";
				out = new FileOutputStream(newJPEGFileName);
				JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
				encoder.encode(bufferImage);
				boolean isSuccess = jpgTotiff(newJPEGFileName, newTIFFileName);
				if (isSuccess) {
					pageAll_temp++;
				}
				if (out != null) {
					out.flush();
					out.close();
				}
				if (img != null) {
					img.flush();
				}
				if (bufferImage != null) {
					bufferImage.flush();
				}

				File jpgFile = new File(newJPEGFileName);
				if (jpgFile.exists()) {
					jpgFile.delete();
				}
			}
		} catch (Exception e) {
			log.error("生成JPEG图片错误");
			log.error(e.getMessage());
		} finally {
			log.info("关闭相关的文件操作流");
			try {
				if (buf != null) {
					unmap(buf);
				}
				if (channel != null) {
					channel.close();
				}
				if (raf != null) {
					raf.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (file.exists()) {
				file.delete();
			}
			if (pageAll_temp != pageAll) {
				pageAll = 0;
			}
		}
		return pageAll;
	}

	/**
	 * JPEG转TIF文件
	 * 
	 * @param jpgFilePath
	 *            JPEG图片路径
	 * @param tifFilePath
	 *            TIF图片路径
	 * @return boolean 是否转换成功
	 */
	public static boolean jpgTotiff(String jpgFilePath, String tifFilePath) {
		log.info("JPEG转TIF文件");
		RenderedOp src = JAI.create("fileload", jpgFilePath);
		OutputStream os = null;
		ImageEncoder enc = null;
		boolean isSuccess = false;
		try {
			os = new FileOutputStream(tifFilePath);
			TIFFEncodeParam param = new TIFFEncodeParam();
			enc = ImageCodec.createImageEncoder("TIFF", os, param);
			enc.encode(src);
			isSuccess = true;
		} catch (FileNotFoundException e) {
			isSuccess = false;
			log.error("需要创建的TIF文件路径不正确");
			log.error(e.getMessage());
		} catch (IOException e) {
			isSuccess = false;
			log.error("生成TIF文件失败");
			log.error(e.getMessage());
		} finally {
			log.info("关闭文件操作流");
			try {
				if (os != null) {
					os.flush();
					os.close();
				}
			} catch (IOException e) {
				log.error("关闭文件操作流失败");
				log.error(e.getMessage());
			}
		}
		return isSuccess;
	}

	/**
	 * 释放PDF集合
	 * 
	 * @param buffer
	 */
	public static void unmap(final Object buffer) {
		log.info("释放PDF集合");
		AccessController.doPrivileged(new PrivilegedAction() {
			public Object run() {
				try {
					Method getCleanerMethod = buffer.getClass().getMethod(
							"cleaner", new Class[0]);
					getCleanerMethod.setAccessible(true);
					sun.misc.Cleaner cleaner = (sun.misc.Cleaner) getCleanerMethod
							.invoke(buffer, new Object[0]);
					cleaner.clean();
				} catch (Exception e) {
					log.error("释放PDF集合失败");
					log.error(e.getMessage());
				}
				return null;
			}
		});
	}

	/**
	 * 文档转换成TIF文件
	 * 
	 * @param filePath
	 *            需要转换的文件路径
	 * @return int 转换后文件的数量
	 */
	public static  int changeFile(String filePath) {
		log.info("DOC TXT文档转换成TIF文件");
		String fileType = filePath.substring(filePath.lastIndexOf('.'),
				filePath.length());

		int pagesize = 0;

		if (".doc".equals(fileType)) {
			log.info("doc文档转换");
			pagesize = docToPdf(filePath);
		} else {
			log.info("txt文档转换");
			String pdfFilePath;
			try {
				pdfFilePath = txtToPDF(filePath);
				pagesize = pdfToJpg(pdfFilePath);
			} catch (IOException e) {
				log.error("生成PDF文档失败");
				log.error(e.getMessage());
			}
		}
		return pagesize;
	}

}